import { reactive } from 'vue'
import { ininStockData } from './tableUtil'

function makeKey() {
  return 'xxxxxxxxxxxx4xxxyxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    const r = (Math.random() * 16) | 0
    const v = c === 'x' ? r : (r & 0x3) | 0x8
    return v.toString(16)
  })
}

export default function () {
  // 单个的高度
  let itemHeight = 36
  // 一页的数据量
  let pageSize = 20
  // 记录上一次滚动位置，用于计算是向上滚动还是向下滚动
  let prevTop = null
  // 主要数据源头
  let virtualList = reactive({
    // 全数据
    list: [],
    // visible 列表集合
    visibleList: [],
    // 列表前的占位高度
    beforePlaceHeight: 0,
    // 列表后的占位高度
    afterPlaceHeight: 0,
  })

  /**
   * 初始化虚拟滚动列表。
   * 此函数用于设置虚拟列表的初始状态，包括分配页面号码和决定哪些项是可见的。
   * 它通过对提供的值进行处理来配置虚拟列表的列表和可见页面号码。
   * @param {Array} value - 初始列表数据。
   */
  const initVirtualScroll = (value) => {
    const list = ininStockData(value)
    // 将车型、车辆和车辆冲突占用的列表数据初始化为虚拟列表数据
    virtualList.list = []
    list.forEach((group) => {
      virtualList.list.push({
        id: group.id,
        key: 'carmodel_' + group.id,
        modelName: group.modelName,
        isCarModel: true,
      })
      group.car_columns.forEach((car, index) => {
        const bars = group.columns[index]
        virtualList.list.push({
          key: 'column_' + makeKey(),
          ...car,
          modelName: group.modelName,
          bars,
        })
      })
    })

    // 处理可见列表和无数据的显示状态
    handleVisibleListAndNo(0)
  }
  /**
   * 处理可见列表和非可见列表的划分。
   * 根据当前可视页面号码计算出可视列表的起始和结束位置，进而从总列表中提取出可视部分的列表。
   * 同时计算出列表前后的占位高度，用于虚拟滚动的布局计算。
   * @remarks
   * 此函数不接受任何参数，也不返回任何值。
   * 它主要用于更新虚拟列表的可见部分和相关的布局参数。
   */
  const handleVisibleListAndNo = (start = 0) => {
    // 如果起始位置小于0，则修正为0
    if (start < 0) start = 0
    // 如果结束位置大于列表总长度，则修正为列表的最后一个位置
    let end = start + pageSize
    if (end > virtualList.list.length - 1) end = virtualList.list.length
    // 根据起始和结束位置，从总列表中提取出可视部分的列表
    virtualList.visibleList = virtualList.list.slice(start, end)

    // 计算列表前的占位高度（起始位置乘以每项的高度）
    virtualList.beforePlaceHeight = start * itemHeight
    // 计算列表后的占位高度（总长度减去结束位置后的项数乘以每项的高度）
    virtualList.afterPlaceHeight = (virtualList.list.length - end) * itemHeight
  }
  /**
   * 当虚拟滚动发生时的处理函数。
   * 根据滚动位置动态更新可视页面号码的列表，以实现虚拟滚动列表的高效渲染。
   * @param {number} top - 当前滚动位置的顶部值。
   */
  const onVirtualScroll = (top) => {
    // 如果列表为空，则直接返回，无需处理
    if (virtualList.list.length == 0) return
    // 如果之前有记录的滚动顶部位置
    if (prevTop && prevTop !== top) {
      // 滚动到不可见区域的 item 数量
      const scrolledItemNumber = Math.floor(top / itemHeight)
      handleVisibleListAndNo(scrolledItemNumber)
    }
    // 更新之前的滚动顶部位置为当前值，以便下次滚动时使用
    prevTop = top
  }

  return {
    virtualList,
    initVirtualScroll,
    onVirtualScroll,
  }
}
